package com.cal.utms.model.dealing;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import com.cal.utms.dto.dealing.InsDateSetDto;
import com.cal.utms.entity.Fund;
import com.cal.utms.entity.Instrument;
import com.cal.utms.entity.InstrumentCouponDate;
import com.cal.utms.entity.InstrumentFloatingRate;

public class InsDateSetModel {

	public Instrument updateCouponDates(Instrument instrument, InsDateSetDto insDateSetDto, Fund fund) {

		DateFormat df = new SimpleDateFormat("MM/dd/yyyy", Locale.ENGLISH);
		Date date = null;

		List<InstrumentCouponDate> oldIcdList = instrument.getInstrumentCouponDates();
		List<InstrumentCouponDate> newIcdList = new ArrayList<InstrumentCouponDate>();
		if(oldIcdList != null){
			for(InstrumentCouponDate oicd : oldIcdList){
				if(fund.getUpdateDate().compareTo(oicd.getCouponDate())>=0){
					newIcdList.add(oicd);
				}
			}
		}
		
		InstrumentCouponDate icd = null;
		if (insDateSetDto.getCouponDates() != null && !insDateSetDto.getCouponDates().equals("")) {
			for (String cpnDate : insDateSetDto.getCouponDates().split(";")) {
				try{
					date = df.parse(cpnDate);
					if(fund.getUpdateDate().compareTo(date)<0){
						icd = new InstrumentCouponDate();
						icd.setInstrument(instrument);
						icd.setCouponDate(date);
						newIcdList.add(icd);
					}
				}catch(ParseException e){
					System.out.println("Invalid Coupon date:" + cpnDate
							+ " for deal:");
					e.printStackTrace();
				}
			}

			instrument.setInstrumentCouponDates(newIcdList);
			
		}else{
			insDateSetDto.setSuccess(false);
			insDateSetDto.setStatus("Cannot find requested Coupon Dates!");
			return instrument;
		}

		return instrument;
	}
	
	public Instrument updateFloatingRates(Instrument instrument, InsDateSetDto insDateSetDto, Fund fund) {

		DateFormat df = new SimpleDateFormat("MM/dd/yyyy", Locale.ENGLISH);
		Date startDate = null;
		Date resetDate = null;
		double tempRate = 0;

		List<InstrumentFloatingRate> oldIfrList = instrument.getInstrumentFloatingRates();
		List<InstrumentFloatingRate> newIfrList = new ArrayList<InstrumentFloatingRate>();
		if(oldIfrList != null){
			for(InstrumentFloatingRate oicd : oldIfrList){
				if(fund.getUpdateDate().compareTo(oicd.getStartingDate())>=0){
					newIfrList.add(oicd);
				}
			}
		}
		Collections.sort(newIfrList, new Comparator<InstrumentFloatingRate>() {
		    @Override
		    public int compare(InstrumentFloatingRate lhs, InstrumentFloatingRate rhs) {
		    	return lhs.getStartingDate().compareTo(rhs.getStartingDate());
		    }
		});
		
		InstrumentFloatingRate ifr = null;
		System.out.println("Floating Rates String:");
		System.out.println(insDateSetDto.getFloatingRates());
		if (insDateSetDto.getFloatingRates() != null && !insDateSetDto.getFloatingRates().equals("")) {
			for (String floatingRate : insDateSetDto.getFloatingRates().split(";")) {
				String[] floatingField = floatingRate.split("\\|");				
				try{
					startDate = df.parse(floatingField[0]);
					resetDate = df.parse(floatingField[1]);
				}catch(ParseException e){
					System.out.println("Invalid Coupon date:" + floatingField[0]+ " : "+floatingField[1]+ " for deal:");
					e.printStackTrace();
					startDate=null;
					resetDate=null;
					insDateSetDto.setSuccess(false);
					insDateSetDto.setStatus("Date Parse Error: "+floatingField[0]+ " : "+floatingField[1]);
					return instrument;
				}
				try{
					tempRate = Double.parseDouble(floatingField[2]);
				}catch(NumberFormatException nfe){
					insDateSetDto.setSuccess(false);
					insDateSetDto.setStatus("Rate Parse Error: "+floatingField[2]);
					return instrument;
				}
				if(startDate!=null && resetDate!=null){					
					if(fund.getUpdateDate().compareTo(startDate)<0){
						if(!newIfrList.isEmpty()){
							Date preStartDate = newIfrList.get(newIfrList.size()-1).getStartingDate();
							int dayRange = (int)( (startDate.getTime() - preStartDate.getTime()) / (1000 * 60 * 60 * 24));
							if(dayRange>instrument.getResetPeriod()){
								insDateSetDto.setSuccess(false);
								insDateSetDto.setStatus("Date Range Larger than reset period");
								return instrument;
							}else{
								ifr = new InstrumentFloatingRate();
								ifr.setInstrument(instrument);
								ifr.setStartingDate(startDate);
								ifr.setNextReset(resetDate);
								ifr.setRate(new BigDecimal(tempRate));
								newIfrList.add(ifr);
							}
						}else if(instrument.getIssueDate().compareTo(startDate)>=0){
							ifr = new InstrumentFloatingRate();
							ifr.setInstrument(instrument);
							ifr.setStartingDate(startDate);
							ifr.setNextReset(resetDate);
							ifr.setRate(new BigDecimal(tempRate));
							newIfrList.add(ifr);
						}else{
							insDateSetDto.setSuccess(false);
							insDateSetDto.setStatus("Date Mismatch error");
							return instrument;
						}
					}
				}
			}
			instrument.setInstrumentFloatingRates(newIfrList);			
		}else{
			insDateSetDto.setSuccess(false);
			insDateSetDto.setStatus("Cannot find requested Coupon Dates!");
			return instrument;
		}
		return instrument;
	}

}
